﻿/*-----------------------------------------------
// File: BCUltimateState.cs
// Description: 
// Author: Shaobing	492057342@qq.com
-----------------------------------------------*/
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace Battle.View
{
    public class BCUltimateState : Fsm.FsmStateMonoBase<ActorState>
    {
        BattleCharacter bc
        {
            get
            {
                return this.controller as BattleCharacter;
            }
        }
        public BCUltimateState(ActorState state, BattleCharacter ctrl) : base(state, ctrl) { }

        UltimateBehaviourPackage currentPackage
        {
            get { return BattleViewCtrl.GetInstance().GetUltimatePackage(); }
        }

        UltimateState ultimateState
        {
            get
            {
                var runningState = BattleViewCtrl.GetInstance().GetCurrentState() as BattleRunningState;
                if (runningState != null)
                {
                    return runningState.GetCurrentState<UltimateState>();
                }
                return null;
            }
        }

        public enum BCUltimatePhase
        {
            None,
            MoveBack,
            Attacking,
        }
        public BCUltimatePhase currentPhase = BCUltimatePhase.None;

        #region MoveBack
        bool isStand = false;
        Vector3 targetPos
        {
            get { return bc.GetStandPosition(); }
        }
        Vector3 moveDir;
        float moveSpeed;
        float moveTime
        {
            get { return bc.GetAniLength(AniName.JUMP_BACKWARD); }
        }
        public void MoveBack()
        {
            moveSpeed = 0;
            moveDir = Vector2.zero;
            bc.PlayUltimateReady();
            //bc.transform.localPosition = targetPos;
            if (bc.ultiSingParticleData != null)
            {
                ultiSingObj = bc.PlayParticle(bc.ultiSingParticleData, false);
            }
            CommonMethod.ChangeParticleLayer(bc.transform, "SceneParticle");
            ModelRenderKit mrk = bc.model.GetComponent<ModelRenderKit>();
            mrk.skinnedMeshRenderer.updateWhenOffscreen = true;
            isStand = true;
            currentPhase = BCUltimatePhase.MoveBack;
            /*
            deltaTime = 0f;
            var dis = Vector3.Distance(targetPos, bc.transform.localPosition);
            if (dis > 0)
            {
                moveSpeed = Vector3.Distance(bc.transform.localPosition, targetPos) / ((float)bc.jumpBackFallTime - (float)bc.jumpBackFlyTime);
                moveDir = (targetPos - bc.transform.localPosition).normalized;
                bc.PlayJumpBackward();
                isStand = false;
            }
            else {
                moveSpeed = 0;
                moveDir = Vector2.zero;
                bc.PlayStand();
                if (bc.ultiSingParticleData != null) {
                    var obj = BattleFactory.SpawnParticle(bc.ultiSingParticleData);
                    CommonMethod.ChangeLayer(obj.obj.transform, "SceneActorFocus");
                    if (obj.obj != null) {
                        bc.PlayParticle(obj);
                        ultiSingObj = obj;
                    }
                }
                isStand = true;
            }
            currentPhase = BCUltimatePhase.MoveBack;
            */

        }
        ParticleObj ultiSingObj = null;
        internal void MoveBackTick()
        {
            if (!isStand)
            {
                deltaTime += Time.deltaTime;
                if (deltaTime >= bc.jumpBackFlyTime && deltaTime <= bc.jumpBackFallTime)
                {
                    var newPos = bc.transform.localPosition + moveDir * moveSpeed * Time.deltaTime;
                    bc.transform.localPosition = newPos;
                }
                if (deltaTime > moveTime)
                {
                    isStand = true;
                    if (bc.ultiSingParticleData != null)
                    {
                        ultiSingObj = bc.PlayParticle(bc.ultiSingParticleData, false);
                    }
                    bc.PlayStand();
                }
            }
        }
        #endregion

        #region Attacking
        UltimateSkill currentSkill;
        float deltaTime = 0f;
        UltimateLogic ultimateLogic
        {
            get
            {
                return BattleViewCtrl.GetInstance().GetUltimateLogic(bc.GetSkill(SkillType.Ultimate).HSId);
            }
        }
        public void UltimateAttack()
        {
            deltaTime = 0f;
            if(ultimateLogic != null)
            {
                if (ultimateLogic.GetComponent<UltimateData>().sourcePoints.Count > 0)
                {
                    bc.transform.SetParent(ultimateLogic.GetComponent<UltimateData>().sourcePoints[0]);
                }
                else
                {
                    bc.transform.SetParent(ultimateLogic.transform);
                }
            }
            
            bc.transform.localPosition = Vector3.zero;
            bc.transform.localScale = Vector3.one;
            bc.transform.localEulerAngles = Vector3.zero;

            bc.model.transform.localScale = Vector3.one;

            var skill = bc.GetSkill(SkillType.Ultimate) as UltimateSkill;
            if (skill.isChangeWeapon())
            {
                bc.model.GetComponent<ModelRenderKit>().UltimateChangeWeapons(skill.changeLeftWeaponId, skill.changeRightWeaponId);
            }
            this.currentSkill = skill;

            bc.anim.EnterForceFace();

            if (ultiSingObj != null)
            {
                ultiSingObj.Recycle();
            }
            currentSkill.Do();
            currentPhase = BCUltimatePhase.Attacking;
        }
        internal void UltimateAttackTick()
        {
            deltaTime += Time.deltaTime;
            foreach (var info in currentSkill.faceChangeInfo)
            {
                if (deltaTime >= info.startTime && deltaTime <= info.stopTime)
                {
                    bc.anim.ChangeCommonFace(info.faceId);
                    break;
                }
            }
        }

        public void OnSkillRelease(BattleSkillRelease release)
        {
            behitAudioQueue.Enqueue(release.beHitAudio);
            //ViewRespectCtrl.GetInstance().AddRespect(release.HeroUid, release.SkillType, release.HSRId, OnSkillReleaseCallBack);

            var curRelease = release;
            var audio = behitAudioQueue.Dequeue();
            // 大招过程中，直接播被击动画
            foreach (var target in ultimateState.targetBCs)
            {
                var state = target.GetCurrentState() as BCBeUltimatedState;
                if (state != null)
                {
                    state.OnSkillRelease(curRelease);
                }
                target.PlayBehitAudio(audio);
            }

            BattleCharacter targetBC = null;
            if (currentPackage.targetUids.Count > 0)
            {
                targetBC = BattleViewCtrl.GetInstance().GetBattleCharacter(currentPackage.targetUids[0]);
            }

            currentSkill.OnSkillRelease(release, targetBC);
        }
        //期望播放的被攻击hitAudio队列
        Queue<string> behitAudioQueue = new Queue<string>();

        void OnSkillReleaseCallBack(ResponseBase rb)
        {
            if (ultimateState == null)
            {
                Debug.LogError("[BCUltimateState OnSkillReleaseCallBack] Not In UltimateState!! State: " + BattleViewCtrl.GetInstance().GetCurrrentStateType().ToString());
                return;
            }
            var attackPackage = rb.packageData as OnceAttackPackage;
            if (attackPackage == null)
            {
                Debug.LogError("[BCAttackState OnSkillReleaseCallBack] Response Not Have OnceAttackPackage. TYPE:" + rb.packageData.GetType().ToString());
                return;
            }

            ultimateState.AddOnceAttackCache(rb.packageData);
            attackPackage.UltimateDeal();

          

        }
        #endregion


        public override void Enter()
        {
            currentPhase = BCUltimatePhase.None;
            bc.OnEnterUltimate();
        }

        public override void Leave()
        {
            ModelRenderKit mrk = bc.model.GetComponent<ModelRenderKit>();
            mrk.skinnedMeshRenderer.updateWhenOffscreen = false;
            bc.transform.SetParent(BattleViewCtrl.GetInstance().transform);
            bc.transform.localPosition = bc.GetStandPosition();
            bc.transform.localEulerAngles = bc.GetStandEulerAngle();
            bc.transform.localScale = Vector3.one;


            bc.model.GetComponent<ModelRenderKit>().SetModelScale(bc.modelScale);
            bc.StartCoroutine(ResetWeapon());
            //var skill = bc.GetSkill(SkillType.Ultimate) as UltimateSkill;
            //if (skill.isChangeWeapon())
            //{
            //    bc.model.GetComponent<ModelRenderKit>().UnloadWeapons();
            //    bc.StartCoroutine(
            //    bc.model.GetComponent<ModelRenderKit>().LoadWeapons(bc.heroId, bc.weaponId));
            //}
            bc.model.GetComponent<LegacyAnimation>().ResetFace();
            CommonMethod.ChangeLayer(bc.model.transform, "SceneActor");
            CommonMethod.ChangeParticleLayer(bc.model.transform, "SceneParticle");
            bc.model.GetComponent<ModelRenderKit>().SetWeaponEffectLayer("SceneParticle");
            bc.PlayStand(true);
            bc.OnLeaveUltimate();
        }
        IEnumerator ResetWeapon()
        {
            var skill = bc.GetSkill(SkillType.Ultimate) as UltimateSkill;
            if (skill.isChangeWeapon())
            {
                var mrk = bc.model.GetComponent<ModelRenderKit>();
                mrk.UnloadWeapons();
                yield return bc.StartCoroutine(mrk.LoadWeapons(bc.heroId, bc.weaponId));

                if (mrk.leftWeapon != null)
                {
                    CommonMethod.ChangeLayer(mrk.leftWeapon.transform, "SceneActor");
                }
                if (mrk.rightWeapon != null)
                {
                    CommonMethod.ChangeLayer(mrk.rightWeapon.transform, "SceneActor");
                }

            }
        }

        public override void Update()
        {
            if (currentPhase == BCUltimatePhase.None)
            {
                MoveBack();
            }
            else if (currentPhase == BCUltimatePhase.MoveBack)
            {
                MoveBackTick();
            }
            else if (currentPhase == BCUltimatePhase.Attacking)
            {
                UltimateAttackTick();
            }
        }

        public void Skip()
        {
            bc.SwitchState(ActorState.AttackReady);
            if (ultiSingObj != null)
            {
                ultiSingObj.Recycle();
            }
        }
    }
}